public class Percolation {
    // creates n-by-n grid, with all sites initially blocked
    public union_find site;
    public union_find fullSite;
    //完整站点的进度条，一旦其周围四个站点打开，则解锁这个完整站点
    public int fullSiteWeight[];  
    public int row_col;
    public int numberOfOpenSites=0;
    //site的对照是，数组的第一个位置用来做连接打开的虚拟点，也就是0，剩下的位置正好和逻辑上对应
    //fullsite的对照是，数组的第一个位置和最后一个位置做虚拟点，剩下的位置逻辑上对应
    //fullSiteWeight的对照是，逻辑上对应，舍弃第0位
    public Percolation(int n)
    {
        row_col=n;
        fullSiteWeight=new int[(n-1)*(n-1)+1];
        //all site and one virtual site to union with
        site=new union_find(n*n+1);
        //all full site and two virtual site which will be used to judge
        fullSite=new union_find((n-1)*(n-1)+2);
        for(int i=1;i<=row_col-1;i++)
        {
            fullSite.union(i, 0);
            fullSite.union((n-1)*(n-2)+i, (n-1)*(n-1)+1);
        }
    }


    // opens the site (row, col) if it is not open already
    public void open(int row, int col)
    {
       site.union(row_col*(row-1)+col,0);  //涉及物理上的对照
       //把有可能的四个完整站点都更改，当然更改条件式站点存在
       if((row-1!=0)&&(col-1!=0))  //左上站点 不是第一行且不是第一列
       {
        fullSiteWeight[(row_col-1)*(row-2)+col-1]++;
        if(fullSiteWeight[(row_col-1)*(row-2)+col-1]==4)
        {
            fullSite.union((row_col-1)*(row-2)+col-1,0);
        }
       }
       if((row-1!=0)&&(col!=row_col))              //右上站点  不是第一行且不是最后一列
       {
        fullSiteWeight[(row_col-1)*(row-2)+col]++;
        if(fullSiteWeight[(row_col-1)*(row-2)+col]==4)
        {
            fullSite.union((row_col-1)*(row-2)+col,0);
        }
       }
       if((col-1!=0)&&(row!=row_col))              //左下站点  不是第一列且不是最后一行
       {
        fullSiteWeight[(row_col-1)*(row-1)+col-1]++;
        if(fullSiteWeight[(row_col-1)*(row-1)+col-1]==4)
        {
            fullSite.union((row_col-1)*(row-1)+col-1,0);
        }
       }
       if((col!=row_col)&&(row!=row_col))           //右下站点   不是最后一行且不是最后一列
       {
        fullSiteWeight[(row_col-1)*(row-1)+col]++;
        if(fullSiteWeight[(row_col-1)*(row-1)+col]==4)
        {
            fullSite.union((row_col-1)*(row-1)+col,0);
        }
       }
    }

    // is the site (row, col) open?
    public boolean isOpen(int row, int col)
    {
        return site.connected((row_col)*(row-1)+col,0);
    }

    // is the site (row, col) full?
    public boolean isFull(int row, int col)
    {
        return isOpen(row, col);         //这里是错的，但是我不想改了，应该对最后结果没有影响
    }

    // returns the number of open sites
    public int numberOfOpenSites()
    {
        return numberOfOpenSites;
    }

    // does the system percolate?
    public boolean percolates()
    {
        return fullSite.connected(0, (row_col-1)*(row_col-1)+1);
    }
}
